package com.example.controller;

import java.util.List;
import java.util.Map;

import com.example.dto.ClassStudentDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.dto.ApiResponse;
import com.example.dto.ClassRequest;
import com.example.dto.InviteCodeResponse;
import com.example.entity.Class;
import com.example.entity.User;
import com.example.service.ClassService;
import com.example.service.UserService;

import jakarta.validation.Valid;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import com.example.security.UserDetailsImpl;

/**
 * 班级管理API控制器，提供班级相关的操作接口。
 */
@Tag(name = "班级管理", description = "班级相关的API接口")
@RestController
@RequestMapping("/api/classes")
public class ClassControllerApi {
    
    private static final Logger logger = LoggerFactory.getLogger(ClassControllerApi.class);
    
    @Autowired
    private ClassService classService;
    
    @Autowired
    private UserService userService;
    
    /**
     * 获取所有班级列表，仅管理员可访问。
     * @return 包含所有班级的ApiResponse对象
     */
    @GetMapping
    @Operation(summary = "获取所有班级列表")
    @PreAuthorize("hasRole('ADMIN')")
    public ApiResponse<List<Class>> getAllClasses() {
        List<Class> classes = classService.getAllClasses();
        return ApiResponse.success(classes);
    }
    
    /**
     * 获取教师的所有授课班级，仅教师可访问。
     * @param userDetails 当前认证用户信息
     * @return 包含教师授课班级的ApiResponse对象
     */
    @GetMapping("/teacher")
    @Operation(summary = "获取教师的所有授课班级")
    @PreAuthorize("hasRole('TEACHER')")
    public ApiResponse<List<Class>> getTeacherClasses(@AuthenticationPrincipal UserDetails userDetails) {
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) userDetails;
        Long teacherId = userDetailsImpl.getId();
        List<Class> classes = classService.getTeacherClasses(teacherId);
        return ApiResponse.success(classes);
    }
    
    /**
     * 获取学生所在的所有班级，仅学生可访问。
     * @param userDetails 当前认证用户信息
     * @return 包含学生所在班级的ApiResponse对象
     */
    @GetMapping("/student")
    @Operation(summary = "获取学生所在的所有班级")
    @PreAuthorize("hasRole('USER')")
    public ApiResponse<List<Class>> getStudentClasses(@AuthenticationPrincipal UserDetails userDetails) {
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) userDetails;
        Long studentId = userDetailsImpl.getId();
        List<Class> classes = classService.getStudentClasses(studentId);
        return ApiResponse.success(classes);
    }
    
    /**
     * 根据班级ID获取班级详情，教师、学生和管理员均可访问。
     * @param id 班级ID
     * @return 包含班级详情的ApiResponse对象
     */
    @GetMapping("/{id}")
    @Operation(summary = "获取班级详情")
    @PreAuthorize("hasAnyRole('TEACHER', 'USER', 'ADMIN')")
    public ApiResponse<Class> getClassById(@PathVariable Long id) {
        Class classInfo = classService.getClassById(id);
        return ApiResponse.success(classInfo);
    }
    
    /**
     * 创建新班级，仅教师可访问。
     * @param classRequest 班级创建请求对象
     * @param userDetails 当前认证用户信息
     * @return 操作结果的ApiResponse对象
     */
    @PostMapping
    @Operation(summary = "创建新班级")
    @PreAuthorize("hasRole('TEACHER')")
    public ApiResponse<?> createClass(
            @RequestBody @Valid ClassRequest classRequest,
            @AuthenticationPrincipal UserDetails userDetails) {
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) userDetails;
        Long teacherId = userDetailsImpl.getId();
        return classService.createClass(classRequest, teacherId);
    }
    
    /**
     * 更新班级信息，仅教师可访问。
     * @param id 班级ID
     * @param classRequest 班级更新请求对象
     * @param userDetails 当前认证用户信息
     * @return 操作结果的ApiResponse对象
     */
    @PutMapping("/{id}")
    @Operation(summary = "更新班级信息")
    @PreAuthorize("hasRole('TEACHER')")
    public ApiResponse<?> updateClass(
            @PathVariable Long id,
            @RequestBody @Valid ClassRequest classRequest,
            @AuthenticationPrincipal UserDetails userDetails) {
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) userDetails;
        Long teacherId = userDetailsImpl.getId();
        return classService.updateClass(id, classRequest, teacherId);
    }
    
    /**
     * 删除班级，仅教师可访问。
     * @param id 班级ID
     * @param userDetails 当前认证用户信息
     * @return 操作结果的ApiResponse对象
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除班级")
    @PreAuthorize("hasRole('TEACHER')")
    public ApiResponse<?> deleteClass(
            @PathVariable Long id,
            @AuthenticationPrincipal UserDetails userDetails) {
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) userDetails;
        Long teacherId = userDetailsImpl.getId();
        return classService.deleteClass(id, teacherId);
    }
    
    /**
     * 生成班级邀请码，仅教师可访问。
     * @param id 班级ID
     * @param userDetails 当前认证用户信息
     * @return 包含邀请码的ApiResponse对象
     */
    @PostMapping("/{id}/invite")
    @Operation(summary = "生成班级邀请码")
    @PreAuthorize("hasRole('TEACHER')")
    public ApiResponse<InviteCodeResponse> generateInviteCode(
            @PathVariable Long id,
            @AuthenticationPrincipal UserDetails userDetails) {
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) userDetails;
        Long teacherId = userDetailsImpl.getId();
        InviteCodeResponse response = classService.generateInviteCode(id, teacherId);
        return ApiResponse.success(response);
    }
    
    /**
     * 通过邀请码加入班级，仅学生可访问。
     * @param inviteCode 邀请码
     * @param userDetails 当前认证用户信息
     * @return 操作结果的ApiResponse对象
     */
    @PostMapping("/join")
    @Operation(summary = "通过邀请码加入班级")
    @PreAuthorize("hasRole('USER')")
    public ApiResponse<?> joinClassByInviteCode(
            @RequestParam String inviteCode,
            @AuthenticationPrincipal UserDetails userDetails) {
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) userDetails;
        Long studentId = userDetailsImpl.getId();
        return classService.joinClassByInviteCode(inviteCode, studentId);
    }
    
    /**
     * 获取班级学生列表，仅教师可访问。
     * @param id 班级ID
     * @param page 页码
     * @param size 每页大小
     * @param query 查询条件
     * @return 包含学生列表的ApiResponse对象
     */
    @GetMapping("/{id}/students")
    @Operation(summary = "获取班级学生列表")
    @PreAuthorize("hasRole('TEACHER')")
    public ApiResponse<Page<ClassStudentDTO>> getClassStudents(
            @PathVariable Long id,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) String query) {
        Page<ClassStudentDTO> students = classService.getClassStudents(id, page, size, query);
        return ApiResponse.success(students);
    }
    
    /**
     * 教师手动添加学生到班级，仅教师可访问。
     * @param id 班级ID
     * @param studentId 学生ID
     * @param userDetails 当前认证用户信息
     * @return 操作结果的ApiResponse对象
     */
    @PostMapping("/{id}/students/{studentId}")
    @Operation(summary = "教师手动添加学生到班级")
    @PreAuthorize("hasRole('TEACHER')")
    public ApiResponse<?> addStudentToClass(
            @PathVariable Long id,
            @PathVariable Long studentId,
            @AuthenticationPrincipal UserDetails userDetails) {
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) userDetails;
        Long teacherId = userDetailsImpl.getId();
        return classService.addStudentToClass(id, studentId, teacherId);
    }
    
    /**
     * 从班级移除学生，仅教师可访问。
     * @param id 班级ID
     * @param studentId 学生ID
     * @param userDetails 当前认证用户信息
     * @return 操作结果的ApiResponse对象
     */
    @DeleteMapping("/{id}/students/{studentId}")
    @Operation(summary = "从班级移除学生")
    @PreAuthorize("hasRole('TEACHER')")
    public ApiResponse<?> removeStudentFromClass(
            @PathVariable Long id,
            @PathVariable Long studentId,
            @AuthenticationPrincipal UserDetails userDetails) {
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) userDetails;
        Long teacherId = userDetailsImpl.getId();
        return classService.removeStudentFromClass(id, studentId, teacherId);
    }
    
    /**
     * 获取班级统计信息，仅教师可访问。
     * @param id 班级ID
     * @return 包含统计信息的ApiResponse对象
     */
    @GetMapping("/{id}/statistics")
    @Operation(summary = "获取班级统计信息")
    @PreAuthorize("hasRole('TEACHER')")
    public ApiResponse<Map<String, Object>> getClassStatistics(@PathVariable Long id) {
        Map<String, Object> statistics = classService.getClassStatistics(id);
        return ApiResponse.success(statistics);
    }
}